package main

import (
	"fmt"
	"log"

	"github.com/pgparser/pkg/parser"
)

func main() {
	fmt.Println("PostgreSQL Parser - 语义分析示例")
	fmt.Println("================================")

	// 测试类型推断和名称解析
	testCases := []struct {
		name string
		sql  string
	}{
		{
			name: "基本类型推断",
			sql:  "SELECT 1 + 2, 'hello' || 'world', 3.14 * 2;",
		},
		{
			name: "列引用和表别名",
			sql:  "SELECT u.name, u.age FROM users u WHERE u.age > 18;",
		},
		{
			name: "函数调用类型推断",
			sql:  "SELECT COUNT(*), AVG(salary), MAX(created_at) FROM employees;",
		},
		{
			name: "空值检查",
			sql:  "SELECT name FROM users WHERE email IS NOT NULL;",
		},
		{
			name: "复杂表达式类型推断",
			sql:  "SELECT (salary * 1.1) + bonus, CASE WHEN age > 30 THEN 'senior' ELSE 'junior' END FROM employees;",
		},
	}

	for i, tc := range testCases {
		fmt.Printf("\n测试用例 %d: %s\n", i+1, tc.name)
		fmt.Printf("SQL: %s\n", tc.sql)
		fmt.Println("---")

		// 解析SQL
		ast, err := parser.ParseSQLToAST(tc.sql)
		if err != nil {
			log.Printf("解析错误: %v", err)
			continue
		}

		// 执行语义分析
		analyzer := parser.NewSemanticAnalyzer()
		err = analyzer.AnalyzeStatement(ast)
		if err != nil {
			log.Printf("语义分析错误: %v", err)
			continue
		}

		// 显示分析结果
		switch stmt := ast.(type) {
		case *parser.SelectStmt:
			fmt.Printf("✓ 解析成功: SELECT语句包含 %d 个目标列\n", len(stmt.Targets))
			
			// 显示目标列的类型信息
			for j, target := range stmt.Targets {
				targetType := inferExpressionType(target)
				fmt.Printf("  目标列 %d: 类型 %s\n", j+1, targetType)
			}
			
			// 显示表引用信息
			if len(stmt.From) > 0 {
				fmt.Printf("  引用表: %s\n", stmt.From[0].Name)
				if stmt.From[0].Alias != "" {
					fmt.Printf("  表别名: %s\n", stmt.From[0].Alias)
				}
			}
			
			// 显示WHERE条件类型
			if stmt.Where != nil {
				whereType := inferExpressionType(stmt.Where)
				fmt.Printf("  WHERE条件类型: %s\n", whereType)
			}
			
		default:
			fmt.Printf("✓ 解析成功: %T\n", stmt)
		}
	}
}

// inferExpressionType 推断表达式类型
func inferExpressionType(expr parser.Node) string {
	if expr == nil {
		return "unknown"
	}
	
	switch e := expr.(type) {
	case *parser.Literal:
		switch e.Type {
		case parser.IntegerLiteral:
			return "integer"
		case parser.FloatLiteral:
			return "float"
		case parser.StringLiteral:
			return "string"
		case parser.BooleanLiteral:
			return "boolean"
		case parser.NullLiteral:
			return "null"
		default:
			return "literal"
		}
	case *parser.ColumnRef:
		return "column_reference"
	case *parser.BinaryExpr:
		switch e.Operator {
		case parser.PLUS, parser.MINUS, parser.MULTIPLY, parser.DIVIDE, parser.MODULO:
			return "numeric"
		case parser.CONCAT:
			return "string"
		case parser.EQ, parser.NE, parser.LT, parser.LE, parser.GT, parser.GE:
			return "boolean"
		case parser.AND, parser.OR:
			return "boolean"
		case parser.IS_NULL, parser.IS_NOT_NULL:
			return "boolean"
		default:
			return "binary_expression"
		}
	case *parser.FunctionCall:
		// 根据函数名推断返回类型
		switch e.Name {
		case "COUNT":
			return "integer"
		case "AVG", "SUM":
			return "numeric"
		case "MAX", "MIN":
			return "depends_on_argument"
		case "CONCAT", "UPPER", "LOWER":
			return "string"
		default:
			return "function_result"
		}
	case *parser.CaseExpr:
		return "case_expression"
	default:
		return fmt.Sprintf("%T", expr)
	}
}